#!/bin/bash

# FastAPI项目简化部署脚本
# 使用方法: sudo bash deploy_simple.sh
# 适用于: 项目代码在 /home/fastapi_-project 目录下

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        log_info "请使用: sudo bash deploy_simple.sh"
        exit 1
    fi
}

# 检查项目目录
check_project_dir() {
    if [[ ! -d "/home/fastapi_-project" ]]; then
        log_error "项目目录 /home/fastapi_-project 不存在"
        log_info "请确保项目代码已上传到该目录"
        exit 1
    fi
    
    if [[ ! -f "/home/fastapi_-project/main.py" ]]; then
        log_error "项目目录中未找到 main.py 文件"
        log_info "请确保项目代码完整"
        exit 1
    fi
    
    log_success "项目目录检查通过"
}

# 更新系统
update_system() {
    log_info "更新系统包..."
    apt update && apt upgrade -y
    log_success "系统更新完成"
}

# 安装基础依赖
install_dependencies() {
    log_info "安装基础依赖..."
    
    apt install -y curl wget git vim htop unzip tree \
                   python3 python3-pip python3-venv python3-dev \
                   mysql-server mysql-client \
                   nginx ufw
    
    log_success "基础依赖安装完成"
}

# 配置防火墙
configure_firewall() {
    log_info "配置防火墙..."
    
    ufw --force enable
    ufw allow ssh
    ufw allow 80
    ufw allow 443
    ufw allow 8000
    
    log_success "防火墙配置完成"
}

# 配置MySQL
configure_mysql() {
    log_info "配置MySQL数据库..."
    
    # 启动MySQL服务
    systemctl start mysql
    systemctl enable mysql
    
    # 检查是否已经有.env文件，如果有则使用其中的配置
    if [[ -f "/home/fastapi_-project/.env" ]]; then
        log_info "检测到现有.env文件，使用其中的数据库配置"
        # 从.env文件读取数据库配置，使用更安全的方式
        DB_NAME=$(grep "^MYSQL_DB=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        DB_USER=$(grep "^MYSQL_USER=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        DB_PASSWORD=$(grep "^MYSQL_PASSWORD=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        DB_HOST=$(grep "^MYSQL_HOST=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        
        # 设置默认值
        DB_NAME=${DB_NAME:-fastapi_db}
        DB_USER=${DB_USER:-root}
        DB_PASSWORD=${DB_PASSWORD:-}
        DB_HOST=${DB_HOST:-localhost}
    else
        log_info "使用默认数据库配置"
        DB_NAME=fastapi_db
        DB_USER=root
        DB_PASSWORD=fastapi_password_123
        DB_HOST=localhost
    fi
    
    # 设置root用户密码（如果还没有设置）
    mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '${DB_PASSWORD}';" 2>/dev/null || true
    
    # 创建数据库
    mysql -u root -p${DB_PASSWORD} -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true
    
    # 确保root用户有所有权限
    mysql -u root -p${DB_PASSWORD} -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true
    mysql -u root -p${DB_PASSWORD} -e "FLUSH PRIVILEGES;" 2>/dev/null || true
    
    log_success "MySQL配置完成，数据库: ${DB_NAME}"
}

# 创建必要的目录
create_directories() {
    log_info "创建必要的目录..."
    
    cd /home/fastapi_-project
    
    mkdir -p uploaded_files
    mkdir -p uploaded_files/firmware
    mkdir -p music/tts
    mkdir -p logs
    mkdir -p static
    mkdir -p backups
    
    log_success "目录创建完成"
}

# 创建环境变量文件
create_env_file() {
    log_info "检查环境变量文件..."
    
    if [[ -f "/home/fastapi_-project/.env" ]]; then
        log_warning ".env文件已存在，保留现有配置"
        log_info "请确保.env文件包含所有必要的配置项"
        return
    fi
    
    log_info "创建环境变量文件..."
    
    cat > /home/fastapi_-project/.env << EOF
# 数据库配置
MYSQL_USER=root
MYSQL_PASSWORD=fastapi_password_123
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DB=fastapi_db

# 讯飞语音识别配置（请根据实际情况修改）
IFLYTEK_APPID=your_iflytek_appid
IFLYTEK_APIKEY=your_iflytek_apikey
IFLYTEK_APISECRET=your_iflytek_apisecret
IFLYTEK_HOST=ntrans.xfyun.cn
IFLYTEK_REQUEST_URI=/v2/ots

# 豆包大模型配置（请根据实际情况修改）
DOUBAO_APP_KEY=your_doubao_app_key
DOUBAO_ACCESS_KEY=your_doubao_access_key
DOUBAO_RESOURCE_ID=your_doubao_resource_id
DOUBAO_WS_URL=your_doubao_ws_url
DOUBAO_TTS_CLUSTER=volcano_tts
DOUBAO_TTS_VOICE_TYPE=zh_male_aojiaobazong_emo_v2_mars_bigtts

# 阿里云语音识别配置
ALIYUN_API_KEY=sk-02e1be9ce510429d8c28950a27ac6957
ALIYUN_MODEL=paraformer-realtime-v2
EOF

    chmod 600 /home/fastapi_-project/.env
    log_success "环境变量文件创建完成"
}

# 创建Python虚拟环境
create_venv() {
    log_info "创建Python虚拟环境..."
    
    cd /home/fastapi_-project
    
    if [[ -d "venv" ]]; then
        log_warning "虚拟环境已存在，跳过创建"
    else
        python3 -m venv venv
        log_success "虚拟环境创建完成"
    fi
}

# 安装Python依赖
install_python_deps() {
    log_info "安装Python依赖..."
    
    cd /home/fastapi_-project
    source venv/bin/activate
    
    # 升级pip
    pip install --upgrade pip
    
    # 安装基础依赖
    pip install fastapi uvicorn sqlalchemy pymysql bcrypt python-multipart
    
    # 安装Pydantic相关依赖
    pip install pydantic[email]
    
    # 安装WebSocket相关依赖
    pip install websocket-client websockets
    
    # 安装HTTP请求相关依赖
    pip install requests httpx
    
    # 安装文件处理相关依赖
    pip install aiofiles python-multipart
    
    # 安装模板引擎
    pip install jinja2
    
    # 安装认证相关依赖
    pip install python-jose[cryptography] passlib[bcrypt]
    
    # 安装异步相关依赖
    pip install asyncio
    
    # 如果有requirements.txt，则安装
    if [[ -f "requirements.txt" ]]; then
        pip install -r requirements.txt
    fi
    
    log_success "Python依赖安装完成"
}

# 初始化数据库
init_database() {
    log_info "初始化数据库..."
    
    cd /home/fastapi_-project
    source venv/bin/activate
    
    # 检查是否有init_db.py
    if [[ -f "init_db.py" ]]; then
        log_info "使用init_db.py初始化数据库..."
        python init_db.py
    else
        log_info "手动创建数据库表..."
        # 手动创建表，处理外键约束
        python -c "
from database.database import engine
from models import user, user_stats, ota
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

try:
    # 先删除有外键约束的表
    logger.info('删除旧表...')
    user_stats.Base.metadata.drop_all(bind=engine)
    user.Base.metadata.drop_all(bind=engine)
    ota.Base.metadata.drop_all(bind=engine)
    
    # 重新创建表
    logger.info('创建新表...')
    user.Base.metadata.create_all(bind=engine)
    user_stats.Base.metadata.create_all(bind=engine)
    ota.Base.metadata.create_all(bind=engine)
    
    print('✅ 数据库表创建成功！')
except Exception as e:
    print(f'⚠️ 数据库表创建时出现警告: {e}')
    print('尝试继续创建表...')
    try:
        user.Base.metadata.create_all(bind=engine)
        user_stats.Base.metadata.create_all(bind=engine)
        ota.Base.metadata.create_all(bind=engine)
        print('✅ 数据库表创建成功！')
    except Exception as e2:
        print(f'❌ 数据库表创建失败: {e2}')
        print('请手动检查数据库连接和权限')
"
    fi
    
    log_success "数据库初始化完成"
}

# 创建systemd服务
create_systemd_service() {
    log_info "创建systemd服务..."
    
    cat > /etc/systemd/system/fastapi.service << EOF
[Unit]
Description=FastAPI Application
After=network.target mysql.service
Wants=mysql.service

[Service]
Type=exec
User=root
Group=root
WorkingDirectory=/home/fastapi_-project
Environment=PATH=/home/fastapi_-project/venv/bin
Environment=PYTHONPATH=/home/fastapi_-project
ExecStart=/home/fastapi_-project/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable fastapi
    
    log_success "systemd服务创建完成"
}

# 配置Nginx
configure_nginx() {
    log_info "配置Nginx..."
    
    # 完全清理所有冲突配置
    log_info "清理冲突的Nginx配置..."
    rm -f /etc/nginx/sites-enabled/default
    rm -f /etc/nginx/sites-enabled/fastapi.backup
    rm -f /etc/nginx/conf.d/default.conf
    rm -f /etc/nginx/conf.d/*.conf
    
    # 删除可能存在的冲突配置文件
    rm -f /etc/nginx/sites-available/default
    rm -f /etc/nginx/sites-available/default.backup
    
    # 确保只有我们的配置
    log_info "创建FastAPI Nginx配置..."
    cat > /etc/nginx/sites-available/fastapi << EOF
server {
    listen 80;
    server_name _;

    client_max_body_size 100M;

    # 静态文件处理（优先级更高，放在前面）
    location /static/ {
        alias /home/fastapi_-project/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
        try_files \$uri \$uri/ =404;
    }

    # 文件上传目录
    location /files/ {
        alias /home/fastapi_-project/uploaded_files/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # WebSocket支持
    location /ws/ {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # 健康检查
    location /health {
        proxy_pass http://127.0.0.1:8000;
        access_log off;
    }

    # API代理（放在最后，作为默认处理）
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}
EOF

    # 启用配置
    ln -sf /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
    
    # 设置正确的文件权限
    log_info "设置文件权限..."
    chown -R root:root /home/fastapi_-project/static/
    chmod -R 755 /home/fastapi_-project/static/
    chmod 755 /home/fastapi_-project/
    
    # 验证配置
    log_info "验证Nginx配置..."
    if nginx -t; then
        log_success "Nginx配置语法正确"
    else
        log_error "Nginx配置语法错误"
        exit 1
    fi
    
    # 重启Nginx
    log_info "重启Nginx服务..."
    systemctl restart nginx
    
    # 等待服务启动
    sleep 2
    
    # 测试静态文件访问
    log_info "测试静态文件访问..."
    if curl -s http://localhost/static/user_management.html > /dev/null; then
        log_success "静态文件访问测试成功"
    else
        log_warning "静态文件访问测试失败，但继续部署"
    fi
    
    log_success "Nginx配置完成"
}

# 创建备份脚本
create_backup_script() {
    log_info "创建备份脚本..."
    
    # 获取数据库名称，使用更安全的方式
    if [[ -f "/home/fastapi_-project/.env" ]]; then
        DB_NAME=$(grep "^MYSQL_DB=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        DB_PASSWORD=$(grep "^MYSQL_PASSWORD=" /home/fastapi_-project/.env | cut -d'=' -f2 | tr -d ' ')
        DB_NAME=${DB_NAME:-fastapi_db}
        DB_PASSWORD=${DB_PASSWORD:-}
    else
        DB_NAME=fastapi_db
        DB_PASSWORD=fastapi_password_123
    fi
    
    cat > /home/fastapi_-project/backup_db.sh << EOF
#!/bin/bash
DATE=\$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/home/fastapi_-project/backups"
mkdir -p \$BACKUP_DIR

mysqldump -u root -p${DB_PASSWORD} ${DB_NAME} > \$BACKUP_DIR/${DB_NAME}_\$DATE.sql

# 保留最近7天的备份
find \$BACKUP_DIR -name "*.sql" -mtime +7 -delete

echo "数据库备份完成: \$BACKUP_DIR/${DB_NAME}_\$DATE.sql"
EOF

    chmod +x /home/fastapi_-project/backup_db.sh
    log_success "备份脚本创建完成"
}

# 启动服务
start_services() {
    log_info "启动服务..."
    
    # 启动FastAPI服务
    systemctl start fastapi
    
    # 检查服务状态
    if systemctl is-active --quiet fastapi; then
        log_success "FastAPI服务启动成功"
    else
        log_error "FastAPI服务启动失败"
        systemctl status fastapi
        exit 1
    fi
    
    log_success "所有服务启动完成"
}

# 测试部署
test_deployment() {
    log_info "测试部署..."
    
    # 等待服务启动
    sleep 3
    
    # 测试FastAPI服务
    log_info "测试FastAPI服务..."
    if curl -s http://localhost:8000/v1/?num=123 > /dev/null; then
        log_success "FastAPI服务测试成功！"
    else
        log_warning "FastAPI服务测试失败，请检查日志"
    fi
    
    # 测试Nginx代理
    log_info "测试Nginx代理..."
    if curl -s http://localhost/v1/?num=123 > /dev/null; then
        log_success "Nginx代理测试成功！"
    else
        log_warning "Nginx代理测试失败"
    fi
    
    # 测试静态文件访问
    log_info "测试静态文件访问..."
    if curl -s http://localhost/static/user_management.html > /dev/null; then
        log_success "静态文件访问测试成功！"
    else
        log_warning "静态文件访问测试失败"
    fi
    
    # 测试公网访问（如果可能）
    log_info "测试公网访问..."
    PUBLIC_IP=$(hostname -I | awk '{print $1}')
    if [[ -n "$PUBLIC_IP" ]]; then
        if curl -s http://$PUBLIC_IP/static/user_management.html > /dev/null; then
            log_success "公网访问测试成功！"
        else
            log_warning "公网访问测试失败，请检查防火墙设置"
        fi
    fi
    
    log_success "部署测试完成"
}

# 显示部署完成信息
show_completion_info() {
    log_success "部署完成！"
    echo
    echo "=========================================="
    echo "🎉 FastAPI项目部署成功！"
    echo "=========================================="
    echo
    echo "📁 项目目录: /home/fastapi_-project"
    echo "👤 运行用户: root"
    echo "🗄️  数据库: fastapi_db"
    echo "🌐 访问地址: http://$(hostname -I | awk '{print $1}')"
    echo
    echo "🔧 常用命令:"
    echo "  查看服务状态: sudo systemctl status fastapi"
    echo "  重启服务: sudo systemctl restart fastapi"
    echo "  查看日志: sudo journalctl -u fastapi -f"
    echo "  备份数据库: /home/fastapi_-project/backup_db.sh"
    echo
    echo "📋 测试命令:"
    echo "  测试API: curl http://localhost:8000/v1/?num=123"
    echo "  测试用户管理: curl http://localhost:8000/static/user_management.html"
    echo
    echo "🌐 访问地址:"
    echo "  主页: http://$(hostname -I | awk '{print $1}')"
    echo "  API文档: http://$(hostname -I | awk '{print $1}')/docs"
    echo "  用户管理: http://$(hostname -I | awk '{print $1}')/static/user_management.html"
    echo
    echo "⚠️  重要提醒:"
    echo "   - 请修改.env文件中的SECRET_KEY"
    echo "   - 建议配置SSL证书"
    echo "   - 定期备份数据库"
    echo
}

# 主函数
main() {
    echo "🚀 FastAPI项目简化部署脚本"
    echo "=========================================="
    echo
    
    check_root
    check_project_dir
    update_system
    install_dependencies
    configure_firewall
    configure_mysql
    create_directories
    create_env_file
    create_venv
    install_python_deps
    init_database
    create_systemd_service
    configure_nginx
    create_backup_script
    start_services
    test_deployment
    show_completion_info
}

# 运行主函数
main "$@" 